#pragma once
#include"stdafx.h"
#include "ResizeArray.h"

class SparseMatrix
{
private:
	uint64 rows;		//number of rows
	uint64 cols;		//number of columns
	uint64 dim_matrix;	//ideal matrix dimension

	ResizeArray<float>* _val;
	ResizeArray<uint64>* _col_ind;
	uint64 * _row_ptr;		

	uint64 _row_ptr_count;	//row_ptr length

	void _addRowCol(const uint64 _row, const uint64 _col, float v)
	{
		uint64 c_min = _row_ptr[_row];
		uint64 c_max = _row_ptr[_row + 1];
		for (int i = _row + 1; i < rows + 1; i++)
		{
			_row_ptr[i]++;
		}
		c_max++;
		// si shifta!!!!!!!!
		for (int i = c_min; i < c_max; i++)
		{

		}
	}

public:
	SparseMatrix(uint64 nrows, uint64 ncols)
		: rows(nrows), 
		  cols(ncols), 
		  dim_matrix(nrows * ncols), 
		  _row_ptr_count(nrows + 1)
	{
		_val = new ResizeArray<float>(-1.f, nrows + 1);
		_col_ind = new ResizeArray<uint64>(-1, nrows + 1);
		_row_ptr = new uint64[nrows + 1];

		for (int i = 0; i < nrows + 1; i++)
		{
			_row_ptr[i] = 0;
		}
	}
	inline ~SparseMatrix()
	{
		delete[] _val;
		delete[] _col_ind;
		delete[] _row_ptr;
	}
	inline float& operator() (const uint64 _row, const uint64 _col)
	{
		//uint64 col_start = _row_ptr[_row];
		//if (col_start < 0)
		//{
		//	return 0.f;
		//}

	}

	void Add(const uint64 _row, const uint64 _col, float v)
	{
		uint64 c_min = _row_ptr[_row];
		int i;
		for (int i = c_min + 1; i < _row_ptr_count; i++)
		{
			_row_ptr[i]++;
		}
		uint64 c_max = _row_ptr[_row + 1];
		for (i= c_min; i < c_max; i++)
		{
			if ((*_col_ind)[i] > _col)
			{
				i++;
				break;
			}
			else if ((*_col_ind)[i] == _col)
			{
				_val[i] = v;
				return;
			}
		}
		_val->InsertAt(i - 1, v);
		_col_ind->InsertAt(i - 1, _col);
	}

	inline float operator() (const uint64 _row, const uint64 _col) const
	{
		uint64 c_min = _row_ptr[_row];
		uint64 c_max = _row_ptr[_row + 1];
		
		if (c_min == c_max)
		{
			return 0.f;
		}
		for (int i = c_min; i < c_max; i++)
		{
			if ((*_col_ind)[i] == _col)
				return (*_val)[i];
			if ((*_col_ind)[i] > _col)
				return 0.f;
		}
		return 0.f;


	}
};